iT邦幫忙

2025 iThome 鐵人賽

0
自我挑戰組

使用 DVWA 與 Kali Linux 的攻防學習系列 第 24

【Day 24】剖析跨網站指令碼 (XSS) 的利用與防禦

  • 分享至 

  • xImage
  •  

攻擊流程的本質: 攻擊者將惡意腳本注入到 Web 應用中,該腳本在受害者的瀏覽器上下文中執行,從而繞過了同源政策。XSS 的核心是「瀏覽器信任了來自伺服器的內容」,即使內容中包含了攻擊者注入的惡意部分。

三種類型的技術區分:

第一部分:XSS 的核心本質——信任的濫用
XSS 的根本原因並非伺服器被駭,而是瀏覽器在渲染網頁時,錯誤地執行了由攻擊者提供的惡意腳本 (Script)。

整個攻擊的核心在於,瀏覽器無法分辨一段腳本是由網站開發者所寫,還是由惡意攻擊者注入的。只要腳本出現在網頁的 HTML 內容中,瀏覽器就會一視同仁地執行它。因此,XSS 的攻擊目標是網站的其他用戶,而非網站伺服器本身。攻擊者利用受害者對目標網站的信任,來執行非預期的操作。

第二部分:XSS 的三種類型——技術的深度剖析
理解這三種類型的底層差異,是精通 XSS 的關鍵。

  1. 反射型 XSS (Reflected XSS / Non-Persistent)
    這是最常見也最直接的類型。攻擊 payload 存在於 HTTP 請求中,通常是 URL 參數,然後伺服器在未經驗證和編碼的情況下,直接將這段 payload「反射」到 HTTP 回應的 HTML 頁面中。

攻擊流程:

攻擊者構造一個包含惡意 JavaScript 的 URL。例如:
http://example.com/search?query=alert('XSS')

攻擊者透過社交工程、釣魚郵件等方式,誘騙受害者點擊這個惡意 URL。

受害者的瀏覽器向 example.com 發送請求。

伺服器從 query 參數中獲取 alert('XSS'),並將其直接嵌入到搜尋結果頁面的 HTML 中,例如:

受害者的瀏覽器接收到回應後,解析 HTML 並執行其中的惡意腳本。

關鍵特點:

非持久性: 攻擊 payload 不會被儲存在伺服器上。

需要互動: 必須誘騙用戶點擊特製的連結才能觸發。

  1. 儲存型 XSS (Stored XSS / Persistent)
    這是危害最大、影響範圍最廣的類型。攻擊 payload 被提交並永久儲存在伺服器的後端資料庫中。

攻擊流程:

攻擊者在網站上尋找一個可以提交數據並被儲存的地方,例如:用戶評論區、文章發表、個人資料設定等。

攻擊者提交一段包含惡意 JavaScript 的內容,例如:
這是一篇很棒的文章!

伺服器未經驗證和編碼,將這段內容儲存到資料庫中。

任何其他用戶(受害者)瀏覽包含這條惡意評論的頁面。

伺服器從資料庫中讀取惡意內容,並將其嵌入到 HTML 頁面中。

所有瀏覽此頁面的受害者的瀏覽器,都會執行這段惡意腳本。

關鍵特點:

持久性: 攻擊 payload 被儲存在伺服器上。

無需互動: 只要用戶瀏覽被污染的頁面,就會自動觸發攻擊,形成「XSS 蠕蟲」的潛力。

  1. DOM 型 XSS (DOM-based XSS)
    這是最隱蔽、也最容易被忽略的類型。整個漏洞的觸發和利用完全發生在瀏覽器端,伺服器可能完全不知道攻擊的發生。

攻擊流程:

網站的前端 JavaScript 代碼,會從某個來源(通常是 URL 片段 #)獲取數據,並在未經處理的情況下,使用它來動態修改頁面的 DOM (文件物件模型)。

攻擊者構造一個惡意 URL,例如:
http://example.com/page.html#<img src=1 onerror=alert('DOM-XSS')>

受害者點擊此 URL。瀏覽器向 example.com 請求 page.html。注意,URL 片段 (# 後的內容) 不會被發送到伺服器。

page.html 中可能有一段不安全的 JavaScript 代碼,例如:

這段腳本獲取了 # 後的 標籤,並將其寫入到頁面的 content 元素中。瀏覽器在渲染這個新元素時,會因為 src=1 載入失敗而觸發 onerror 事件,執行其中的惡意腳本。

關鍵特點:

客戶端漏洞: 漏洞存在於前端 JavaScript 代碼中,與後端無關。

伺服器無感知: 惡意 payload 可能永遠不會到達伺服器日誌。

第三部分:XSS 的真實利用——超越 alert(1) 的威力
alert(1) 只是用來證明漏洞存在的概念驗證 (PoC)。在真實世界中,攻擊者會利用 XSS 執行極具破壞性的攻擊:

會話劫持 (Session Hijacking): 這是最核心的威脅。攻擊者注入的腳本可以讀取受害者的 document.cookie,並將其發送到攻擊者控制的伺服器。一旦攻擊者獲得了包含會話 ID 的 Cookie,他就可以將其設定在自己的瀏覽器中,完全冒充受害者登入系統,執行受害者能執行的所有操作。

鍵盤側錄 (Keylogging): 攻擊者可以注入一個鍵盤事件監聽器 (addEventListener('keydown', ...)), 記錄用戶在頁面上(特別是登入表單、密碼框中)輸入的所有內容,並將其發送到遠端伺服器。

介面偽造與釣魚 (UI Redressing & Phishing): 攻擊者可以利用 JavaScript 完全改變頁面的外觀,例如,在一個受信任的網頁上,動態插入一個偽造的登入框,並提示用戶「您的會話已過期,請重新登入」。用戶輸入的憑證將被直接發送給攻擊者。

瀏覽器漏洞利用 (Browser Exploitation): 攻擊者可以利用 XSS 作為跳板,引入更複雜的攻擊框架(如 BeEF - The Browser Exploitation Framework)。一旦受害者的瀏覽器被「鉤住」(hooked),攻擊者就可以像操作木馬一樣遠端控制瀏覽器,發動內網掃描、觸發瀏覽器漏洞等。

繞過 CSRF 防護: 如果一個網站使用了 Anti-CSRF Token 來防禦跨站請求偽造,攻擊者可以利用 XSS 漏洞,先用 AJAX 請求獲取包含 Token 的頁面,從中解析出 Token,然後再用這個 Token 構造出合法的 CSRF 請求。

第四部分:XSS 的縱深防禦——工程化的解決方案
防禦 XSS 不是單靠一個 filter() 函數就能解決的,它需要一個多層次、系統性的防禦策略。

  1. 核心防禦:情境感知輸出編碼 (Context-Aware Output Encoding)
    這是防禦 XSS 最根本、最重要的原則。當你必須將不受信任的數據插入到 HTML 頁面時,必須根據其插入的上下文 (Context) 進行相應的編碼。

插入到 HTML 元素內容中 (HTML Body Context):

場景: [USER_INPUT]

策略: HTML 實體編碼 (HTML Entity Encoding)。將特殊字元轉換為 HTML 實體。

< -> <

-> >

& -> &

" -> "

' -> '

插入到 HTML 屬性中 (HTML Attribute Context):

場景:

策略: 屬性編碼。除了上述 HTML 實體編碼,還應對除字母和數字外的所有字元使用 &#xHH; 格式進行編碼。

插入到 JavaScript 變數中 (JavaScript Context):

場景: var username = '[USER_INPUT]';

策略: JavaScript Unicode 轉義。將非字母數字的字元轉換為 \uXXXX 格式,以防止用戶輸入 '; alert(1); // 這樣的內容來閉合引號並注入新指令。

插入到 URL 中 (URL Context):

場景:

策略: URL 編碼 (Percent Encoding)。

  1. 縱深防禦:內容安全策略 (Content Security Policy - CSP)
    CSP 是一個 HTTP 回應標頭,它就像是為你的網站設定了一個安全「白名單」。你可以告訴瀏覽器,只允許從哪些來源載入和執行腳本、樣式、圖片等資源。

一個嚴格的 CSP 策略可以極大地緩解 XSS 帶來的危害,即使漏洞仍然存在。例如:
Content-Security-Policy: default-src 'self'; script-src 'self' static.example.com;
這個策略表示:預設只信任同源內容;對於腳本,只信任同源 (self) 和 static.example.com 這兩個來源。這將直接禁止所有內聯腳本 (inline script) 和 eval() 的執行,讓許多 XSS payload 失效。

  1. 輔助防禦與良好實踐
    輸入驗證 (Input Validation): 在接收用戶輸入時,就應根據業務邏輯進行驗證。例如,年齡欄位只應接受數字。這是一種良好的編程習慣,可以阻擋一些低級的 XSS 攻擊,但絕不能作為主要的防禦手段,因為攻擊者總能找到繞過黑名單的方法。白名單驗證遠勝於黑名單過濾。

使用 HttpOnly Cookie 屬性: 為你的會話 Cookie 設置 HttpOnly 標誌。這樣一來,即使存在 XSS 漏洞,攻擊者的 JavaScript 也無法透過 document.cookie 讀取到會話 Cookie,有效防禦了最直接的會話劫持攻擊。

利用現代前端框架: 像 React, Angular, Vue 等現代框架,在設計上就內置了 XSS 防護。例如,它們在渲染數據時會預設進行輸出編碼。但開發者仍然需要小心,避免使用 dangerouslySetInnerHTML (React) 或 v-html (Vue) 等會繞過這些安全機制的危險功能

縱深防禦-內容安全策略 (CSP): CSP 是一個 HTTP 回應標頭,它允許網站管理員定義一個「白名單」,明確告知瀏覽器哪些來源的腳本、樣式、圖片等資源是允許載入和執行的。一個嚴格的 CSP 可以極大地緩解即使存在 XSS 注入點時的實際危害。


上一篇
【Day 23】系統性理解注入 (Injection) 攻擊
下一篇
【Day 25】解構失效的身份認證與會話管理
系列文
使用 DVWA 與 Kali Linux 的攻防學習30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言